<?php
namespace Infinity;

class DataTable {

  private $arr_columns, $arr_rows;

  public function __construct() {

    $this->arr_columns = array();
    $this->arr_rows = array();
  }

  public static function loadFromCsvFile($file_path, $has_title=true)
  {
    //setlocale(LC_ALL,array('zh_CN.gbk','zh_CN.gb2312','zh_CN.gb18030'));
    ini_set('auto_detect_line_endings',TRUE);
    if (($handle = fopen($file_path, "r")) !== FALSE) {
      $dt = new DataTable();

      # title
      if (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        if($has_title) {
          for($i=0; $i<count($row); $i++) {
            $dt->addColumn($row[$i]);
          }
        } else {
          for($i=0; $i<count($row); $i++) {
            $dt->addColumn('col'.$i);
            $dt->addRow($row);
          }
        }
      }

      # data body
      while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $dt->addRow($row);
      }

      return $dt;
    }
  }

  public static function loadFromXmlFile($file_path, $xpath='/')
  {
    $xml = simplexml_load_file($file_path);
    $elements = $xml->xpath($xpath);
    $dt = new DataTable();

    foreach($elements as $element)
    {
      foreach($element->children() as $child) {
        if(!in_array($child->getName(), $dt->columns()))
          $dt->addColumn($child->getName());
        dpm((string)$child);
      }
    }
    // TODO:
  }

  public static function loadFromExcelFile($file_path) {
    $include_file = libraries_get_path('PHPExcel').'/PHPExcel.php';
    if(file_exists($include_file)) {
      require_once(libraries_get_path('PHPExcel').'/PHPExcel.php');
    } else {
      drupal_set_message('PHPExcel not installed.', 'error');
      return false;
    }

    $PHPReader = new \PHPExcel_Reader_Excel2007();
    if (!$PHPReader->canRead($file_path)) {
      $PHPReader = new \PHPExcel_Reader_Excel5();
      if (!$PHPReader->canRead($file_path)) {
        drupal_set_message('No Excel', 'error');
        return false;
      }
    }
    $PHPExcel = $PHPReader->load($file_path);
    $currentSheet = $PHPExcel->getSheet(0);
    /**取得一共有多少列*/
    $col = \PHPExcel_Cell::columnIndexFromString($currentSheet->getHighestColumn());
    /**取得一共有多少行*/
    $allRow = $currentSheet->getHighestRow();
    //循环读取每个单元格的内容。注意行从2开始，列从A开始，行1爲key值
    $results = array();

    $dt = new DataTable();
    // title
    for ($colIndex = 0; $colIndex <= $col - 1; $colIndex++) {
      $cell = $currentSheet->getCellByColumnAndRow($colIndex, 1)->getValue();
      $cell = trim($cell);
      if($cell instanceof \PHPExcel_RichText) {
        $cell = $cell->__toString();
      }
      $dt->addColumn($cell);
    }

    for ($rowIndex = 2; $rowIndex <= $allRow; $rowIndex++) {
      $i = 0;
      $fields = array();
      for ($colIndex = 0; $colIndex <= $col - 1; $colIndex++) {
        $cell = $currentSheet->getCellByColumnAndRow($colIndex, $rowIndex)
          ->getValue();
        $cell = trim($cell);
        if($cell instanceof \PHPExcel_RichText) {
          $cell = $cell->__toString();
        }
        $fields[] = $cell;
        $i++;
      }
      $error_fields = array();
      $dt->addRow($fields);
      if ($error_fields) {
        $error_fields = array_unique($error_fields);
        watchdog('loadFromExcelFile', implode(',', $error_fields) . ' 不在预期范围内。');
      }
    }

    return $dt;
  }

  /**
   * @param string $column_name
   */
  public function addColumn($column_name) {
    array_push($this->arr_columns, $column_name);
  }

  /**
   * @param array $arr_name
   */
  public function addColumns(array $arr_name)
  {
    foreach($arr_name as $name) {
      $this->addColumn($name);
    }
  }

  /**
   * @param int $index
   */
  public function deleteColumn($index)
  {
    if(array_key_exists($index, $this->arr_columns)) {
      unset($this->arr_columns[$index]);
      foreach($this->arr_rows as $key => $row) {
        unset($this->arr_rows[$key][$index]);
      }
    }
  }

  public function columns($idx=null) {
    if (is_null($idx) || (string) $idx=="") {
      return $this->arr_columns;
    } else {
      return $this->arr_columns[$idx];
    }
  }

  public function columnIndex($column_name) {
    $array_keys = array_keys($this->arr_columns, $column_name);
    return $array_keys[0];
  }

  public function addRow() {
    $arg_list = func_get_args();
    foreach($arg_list as $arg) {
      $this->arr_rows[] = array_values($arg);
    }
  }

  public function rows($idx=null) {
    if (is_null($idx) || (string) $idx=="") {
      return $this->arr_rows;
    } else {
      return $this->arr_rows[$idx];
    }
  }

  public function objects() {
    $objects = array();
    foreach($this->arr_rows as $row) {
      $object = new \Magento\Framework\DataObject();
      foreach($this->columns() as $i => $name) {
        $object->setData($name, $row[$i]);
      }
      $objects []= $object;
    }
    return $objects;
  }

  /**
   * @return int
   */
  public function total() {
    return count($this->arr_rows);
  }

  public function sort(callable $func)
  {
    return usort($this->arr_rows, $func);
  }

  public function filter(callable $func)
  {
    $this->arr_rows = array_filter($this->arr_rows, $func);
  }

  public function outputAsCsv()
  {
    header('Content-Type:text/html; charset=utf-8');
    header('Content-Type:application/force-download');
    echo implode(",", $this->arr_columns)."\r\n";
    foreach($this->arr_rows as $row) {
      $row = array_map(function($elem){
        return "\t".str_replace('"', '""', $elem);
      }, $row);
      echo '"'.implode("\",\"", $row)."\"\r\n";
    }
    drupal_exit();
  }

  public function outputAsExcel()
  {
    $include_file = libraries_get_path('PHPExcel').'/PHPExcel.php';
    if(file_exists($include_file)) {
      require_once(libraries_get_path('PHPExcel').'/PHPExcel.php');
    } else {
      drupal_set_message('PHPExcel not installed.', 'error');
      return;
    }
    $objPHPExcel = new \PHPExcel();
    $worksheet = $objPHPExcel->getActiveSheet();
    $worksheet->fromArray( $this->arr_columns, NULL, 'A1' );
    $worksheet->fromArray( $this->arr_rows, NULL, 'A2' );
    $objWriter = new \PHPExcel_Writer_Excel2007($objPHPExcel);
    ob_end_clean();
    //$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");
    header("Content-Transfer-Encoding: binary");
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Pragma: no-cache");
    $objWriter->save('php://output');
    drupal_exit();
  }

  public function render()
  {
    return theme('table', array(
      'header' => $this->arr_columns,
      'rows' => $this->arr_rows,
      'empty' => t('No records'),
    ));
  }
}

/*
$dt = new Infinity\DataTable();
$dt->addColumns(array('員工號碼', '員工名字', '課程名字', '日期及時間', '學分', '出席', '測試', 'date'));
$dt->addRow(
  array('xxxxx', 'xxxxx', 'xxxxx', '234', 1, 'Y', 'Y', 234),
  array('xxxxx', 'xxxxx', 'xxxxx', '232', 1, 'Y', 'Y', 232),
  array('xxxxx', 'xxxxx', 'xxxxx', '124', 1, 'Y', 'Y', 124),
  array('xxxxx', 'xxxxx', 'xxxxx', '453', 1, 'Y', 'Y', 453),
  array('xxxxx', 'xxxxx', 'xxxxx', '754', 1, 'Y', 'Y', 754)
);

$index = $dt->columnIndex('date');
// 排序
$dt->sort(function($a, $b) use ($index){
  if($a[$index] == $b[$index]) return 0;
  return $a[$index] > $b[$index] ? 1 : -1;
});
// 过滤
$dt->filter(function($row) use ($index){
  if($row[$index] != 754)
    return true;
  else
    return false;
});
$dt->deleteColumn($index);
echo $dt->render();

// excel下载 （需要安装PHPExcel）
$dt->outputAsExcel();
*/
